<?php
class DBHelper{
	const FAIL = 0;
	const SUCCESS = 1;
	/**
	 * DBHelper Instance.
	 * @var DBHelper
	 */
	private static $_ndb;
	/**
	 * PDO Object
	 * @var DBHelper
	 */
	private $dbo;
	/**
	 * Error info
	 * @var String
	 */
	private $_error;
	/**
	 * Fetch mod.
	 * @var unknown_type
	 */
	private $_fetchMod;
	/**
	 * DB optional
	 * @var unknown_type
	 */
	private $_option = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");

	private function __construct(){
		try{
			$this->_fetchMod = Configuration::DB_FETCHMOD;
			$this->dbo = new PDO('mysql:host='.Configuration::DB_HOSTNAME.';dbname='.Configuration::DB_DBNAME, Configuration::DB_USERNAME, Configuration::DB_PASSWORD,$this->_option);
			$this->dbo->setAttribute(PDO::ATTR_ERRMODE, Configuration::DB_ERROR_MOD);
		}catch(PDOException $exc){
			$this->_error = $exc->getMessage();
			Log::error("PDOException", $exc->getMessage());
			if(Configuration::DEBUG_MOD == true){
				echo $exc->getMessage();
			}
		}
	}
	/**
	 * Return DBHelper Instance.
	 * @return DBHelper
	 */
	public static function getInstance(){
		if(!self::$_ndb){
			self::$_ndb = new DBHelper();
		}
		return self::$_ndb;
	}
	/**
	 *
	 * Return Array of result of query ...
	 * @param $query
	 */
	public function fetchAll($query){
		$result = null;
		try {
			$stmt = $this->dbo->query($query);
			$result = $stmt->fetchAll($this->_fetchMod);
		} catch (PDOException $e) {
			$this->_error = $e->getMessage();
			Log::info("DBHelper", $query);
			Log::error("DBHelper", $e->getMessage());
			if(Configuration::DEBUG_MOD == true){
				throw new DBHelperException($e->getMessage());
			}
		}
		return $result;
	}
/**
	 *
	 * Return number of rows of result...
	 * @param $query
	 */
	public function fetchCount($query){
		$result = 0;
		try {
			$stmt = $this->dbo->query($query);
			$result = count($stmt->fetchAll($this->_fetchMod));
		} catch (PDOException $e) {
			$this->_error = $e->getMessage();
			Log::info("DBHelper", $query);
			Log::error("DBHelper", $e->getMessage());
			if(Configuration::DEBUG_MOD == true){
				throw new DBHelperException($e->getMessage());
			}
		}
		return $result;
	}
	/**
	 *
	 * Query one row ...
	 * @param string $query
	 * @return a first row of query.
	 */
	public function fetchRow($query){
		$array = $this->fetchAll($query);
		if(count($array)>0)
		return $array[0];
		return null;
	}
	/**
	 * Using insert or update query<br>
	 * Execute prepare statement in option ...
	 * @param string $prepare query string
	 * @param array $data mapped data
	 * @return 1/0 is Success or fail.
	 */
	public function executeArray($prepare,array $data){
		$result = DBHelper::FAIL;
		try {
			$sttm = $this->dbo->prepare($prepare);
			$result = $sttm->execute($data);
		} catch (PDOException $e) {
			Log::info("DBHelper", $prepare);
			$this->_error = $e->getMessage();
			Log::error("DBHelper", $e->getMessage());
			if(Configuration::DEBUG_MOD == true){
				throw new DBHelperException($e->getMessage());
			}
		}
		return $result;
	}
	/**
	 * Execute an SQL statement and return the number of affected rows<br>
	 * Using in delete query<br>
	 * Using Transaction.
	 * @param String $query
	 * @return int result
	 */
	public function execute($query){
		$result = 0;
		try {
			$this->dbo->beginTransaction();
			$result = $this->dbo->exec($query);
			$this->dbo->commit();
		} catch (PDOException $e) {
			$this->dbo->rollBack();
			Log::info("DBHelper", $query);
			$this->_error = $e->getMessage();
			Log::error("DBHelper", $e->getMessage());
			if(Configuration::DEBUG_MOD == true){
				throw new DBHelperException($e->getMessage());
			}
		}
		return $result;
	}
	/**
	 *
	 * Set fetch for DB FetchMod ...
	 * @param $fetchMod
	 */
	public function setfetchMod($fetchMod){
		$this->_fetchMod = $fetchMod;
	}
	/**
	 * Executes an SQL statement,<br> 
	 * Returning a result set as a PDOStatement object.
	 * @param $query
	 */
	public function query($query){
		try {
			return $this->dbo->query($query);
		} catch (PDOException $e) {
			Log::info("DBHelper", $query);
			$this->_error = $e->getMessage();
			Log::error("DBHelper", $e->getMessage());
			if(Configuration::DEBUG_MOD == true){
				throw new DBHelperException($e->getMessage());
			}
		}
		return null;
	}
	public function getError(){
		return $this->_error;
	}
	public function setError($error){
		$this->_error = $error;
	}
	/**
	 * Get PDO Object.
	 * @return PDO
	 */
	public function getDBO(){
		return $this->dbo;
	}
}